"""权限管理模块视图 - 使用Django内建权限系统"""
from rest_framework import viewsets, status, serializers
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter, OrderingFilter
from django.contrib.auth.models import User, Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db import transaction
from django.db.models import Q
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiParameter, inline_serializer
from drf_spectacular.types import OpenApiTypes

from apps.common.responses import (
    ApiResponseMixin,
    create_success_response_serializer,
    ValidationErrorResponseSerializer,
    NotFoundErrorResponseSerializer,
    ForbiddenErrorResponseSerializer
)
from apps.common.permissions import IsAdminOrReadOnly
from apps.common.pagination import StandardPagination
from apps.common.mixins import ConfigurableActionMixin
from .models import PermissionCategory, GroupProfile, PermissionProfile, UserGroupAssignment
from .serializers import (
    PermissionCategorySerializer,
    PermissionProfileSerializer,
    PermissionSerializer,
    PermissionListSerializer,
    GroupProfileSerializer,
    GroupSerializer,
    GroupListSerializer,
    GroupDetailSerializer,
    UserGroupAssignmentSerializer,
    AssignGroupSerializer,
    AssignPermissionSerializer,
    UserPermissionSerializer,
    GroupStatusSerializer,
    CreateGroupSerializer,
    GroupUserListSerializer,
    RemoveUsersFromGroupSerializer
)


@extend_schema_view(
    list=extend_schema(
        summary="获取权限列表",
        description="获取Django内建权限列表，支持分页、过滤和排序",
        parameters=[
            OpenApiParameter(name='search', type=OpenApiTypes.STR, description='搜索关键词'),
            OpenApiParameter(name='content_type', type=OpenApiTypes.INT, description='内容类型ID过滤'),
            OpenApiParameter(name='codename', type=OpenApiTypes.STR, description='权限代码名过滤'),
        ],
    ),
    retrieve=extend_schema(
        summary="获取权限详情",
        responses={
            200: create_success_response_serializer(PermissionSerializer, "获取成功", "Retrieve"),
            404: NotFoundErrorResponseSerializer,
        }
    ),
)
class PermissionViewSet(viewsets.ReadOnlyModelViewSet):
    """Django内建权限管理ViewSet - 只读"""
    queryset = Permission.objects.all().select_related('content_type').order_by('content_type__app_label', 'codename')
    permission_classes = [IsAdminUser]
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['content_type', 'codename']
    search_fields = ['name', 'codename', 'content_type__model']
    ordering_fields = ['id', 'name', 'codename']
    ordering = ['content_type__app_label', 'codename']

    def get_serializer_class(self):
        """根据action选择序列化器"""
        if self.action == 'list':
            return PermissionListSerializer
        else:
            return PermissionSerializer


@extend_schema_view(
    list=extend_schema(
        summary="获取组列表",
        description="获取Django内建组列表，支持分页、过滤和排序",
        parameters=[
            OpenApiParameter(name='search', type=OpenApiTypes.STR, description='搜索关键词'),
            OpenApiParameter(name='name', type=OpenApiTypes.STR, description='组名过滤'),
        ],
    ),
    retrieve=extend_schema(
        summary="获取组详情",
        responses={
            200: create_success_response_serializer(GroupDetailSerializer, "获取成功", "Retrieve"),
            404: NotFoundErrorResponseSerializer,
        }
    ),
    create=extend_schema(
        summary="创建组",
        request=CreateGroupSerializer,
        responses={
            201: create_success_response_serializer(GroupSerializer, "创建成功", "Create"),
            400: ValidationErrorResponseSerializer,
            403: ForbiddenErrorResponseSerializer,
        }
    ),
    update=extend_schema(
        summary="更新组",
        responses={
            200: create_success_response_serializer(GroupSerializer, "更新成功", "Update"),
            400: ValidationErrorResponseSerializer,
            404: NotFoundErrorResponseSerializer,
            403: ForbiddenErrorResponseSerializer,
        }
    ),
    destroy=extend_schema(
        summary="删除组",
        responses={
            204: None,
            404: NotFoundErrorResponseSerializer,
            403: ForbiddenErrorResponseSerializer,
        }
    ),
)
class GroupViewSet(ConfigurableActionMixin, ApiResponseMixin, viewsets.ModelViewSet):
    """Django内建组管理ViewSet"""
    queryset = Group.objects.all().prefetch_related('permissions').order_by('name')
    permission_classes = [IsAdminUser]
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['name']
    search_fields = ['name', 'profile__display_name', 'profile__description']
    ordering_fields = ['id', 'name']
    ordering = ['name']
    # 🔑 关键：设置分页器，让DRF能够推断自定义Action的分页Schema
    pagination_class = StandardPagination

    # 🔑 关键：配置式Action配置 - 支持ViewSet标准配置格式
    action_configs = {
        'permissions': {
            'use_pagination': True,  # 模式1：强制分页配置
            'search_fields': ['name', 'codename', 'content_type__model'],  # URL: ?search=关键词
            'filterset_fields': {
                'name': ['exact', 'icontains'],  # URL: ?name=值 或 ?name__icontains=值
                'codename': ['exact', 'icontains'],  # URL: ?codename=值 或 ?codename__icontains=值
                'content_type__app_label': ['exact'],  # URL: ?content_type__app_label=auth
                'content_type__model': ['exact', 'icontains'],  # URL: ?content_type__model=user
                'content_type_id': ['exact', 'in'],  # URL: ?content_type_id=1 或 ?content_type_id__in=1,2,3
                'content_type': 'content_type_id',  # URL: ?content_type=1 (自定义参数映射)
                'app_label': 'content_type__app_label',  # URL: ?app_label=auth (自定义参数映射)
            },
            'ordering_fields': ['content_type__app_label', 'codename', 'name'],  # URL: ?ordering=字段名
            'ordering': ['content_type__app_label', 'codename'],  # 默认排序
            # 完整URL示例: GET /api/permissions/groups/1/permissions/?search=user&app_label=auth&ordering=-codename&page=1&page_size=20
        },
        'users': {
            'use_pagination': True,  # 模式3：强制不分页配置
            'search_fields': ['username', 'email', 'first_name', 'last_name'],  # URL: ?search=关键词
            'filterset_fields': ['is_active', 'is_staff'],  # URL: ?is_active=true&is_staff=false
            'ordering_fields': ['username', 'email', 'date_joined', 'last_login'],  # URL: ?ordering=字段名
            'ordering': ['username'],  # 默认排序
            # 完整URL示例: GET /api/permissions/groups/1/users/?search=test&is_active=true&ordering=-username
        },
    }

    def get_serializer_class(self):
        """根据action选择序列化器"""
        if self.action == 'list':
            return GroupListSerializer
        elif self.action == 'retrieve':
            return GroupDetailSerializer
        elif self.action == 'create':
            return CreateGroupSerializer
        else:
            return GroupSerializer

    def create(self, request, *args, **kwargs):
        """创建组"""
        serializer = CreateGroupSerializer(data=request.data)
        if not serializer.is_valid():
            return self.error_response("参数无效", errors=serializer.errors, code=400)

        with transaction.atomic():
            # 创建Django内建Group
            group = Group.objects.create(name=serializer.validated_data['name'])

            # 创建GroupProfile扩展信息
            GroupProfile.objects.create(
                group=group,
                display_name=serializer.validated_data['display_name'],
                description=serializer.validated_data.get('description', ''),
                is_system=serializer.validated_data.get('is_system', False),
                created_by=request.user
            )

        response_serializer = GroupSerializer(group)
        return self.success_response(
            data=response_serializer.data,
            message="组创建成功",
            code=201
        )

    def perform_destroy(self, instance):
        """删除组前检查"""
        # 检查是否为系统组
        if hasattr(instance, 'profile') and instance.profile.is_system:
            raise ValidationError("系统组不允许删除")

        # 检查是否有用户关联
        if instance.user_set.exists():
            raise ValidationError("该组下还有用户，无法删除")

        super().perform_destroy(instance)

    @extend_schema(
        summary="分配权限给组",
        request=AssignPermissionSerializer,
        responses={
            200: create_success_response_serializer(GroupDetailSerializer, "权限分配成功", "AssignPermissions"),
            400: ValidationErrorResponseSerializer,
            404: NotFoundErrorResponseSerializer,
        }
    )
    @action(detail=True, methods=['post'])
    def assign_permissions(self, request, pk=None):
        """分配权限给组"""
        group = self.get_object()

        # 检查是否为系统组
        if hasattr(group, 'profile') and group.profile.is_system:
            return self.error_response("系统组不允许修改权限", code=400)

        serializer = AssignPermissionSerializer(data=request.data)
        if not serializer.is_valid():
            return self.error_response("参数无效", errors=serializer.errors, code=400)

        permission_ids = serializer.validated_data['permission_ids']

        with transaction.atomic():
            # 清除现有权限
            group.permissions.clear()

            # 分配新权限
            permissions = Permission.objects.filter(id__in=permission_ids)
            group.permissions.set(permissions)

        response_serializer = GroupDetailSerializer(group)
        return self.success_response(
            data=response_serializer.data,
            message="权限分配成功"
        )

    @extend_schema(
        summary="分配用户到组",
        request=AssignGroupSerializer,
        responses={
            200: create_success_response_serializer(GroupDetailSerializer, "用户分配成功", "AssignUsers"),
            400: ValidationErrorResponseSerializer,
            404: NotFoundErrorResponseSerializer,
        }
    )
    @action(detail=True, methods=['post'])
    def assign_users(self, request, pk=None):
        """分配用户到组"""
        group = self.get_object()

        serializer = AssignGroupSerializer(data=request.data)
        if not serializer.is_valid():
            return self.error_response("参数无效", errors=serializer.errors, code=400)

        user_ids = serializer.validated_data['user_ids']
        expires_at = serializer.validated_data.get('expires_at')
        notes = serializer.validated_data.get('notes', '')

        with transaction.atomic():
            users = User.objects.filter(id__in=user_ids)

            # 添加用户到组
            group.user_set.add(*users)

            # 创建分配记录
            assignments = []
            for user in users:
                assignments.append(UserGroupAssignment(
                    user=user,
                    group=group,
                    assigned_by=request.user,
                    expires_at=expires_at,
                    notes=notes
                ))

            UserGroupAssignment.objects.bulk_create(assignments, ignore_conflicts=True)

        response_serializer = GroupDetailSerializer(group)
        return self.success_response(
            data=response_serializer.data,
            message="用户分配成功"
        )

    @extend_schema(
        summary="获取组权限列表",
        description="获取指定组的权限列表，支持分页、搜索、过滤",
        parameters=[
            # 可以省略page, page_size, ordering, search
            # 按需要定义,
            OpenApiParameter(name='content_type', type=OpenApiTypes.INT, description='内容类型ID过滤'),
            OpenApiParameter(name='app_label', type=OpenApiTypes.STR, description='应用标签过滤'),
        ],
        request=None,
        # 🔑 关键：对于自定义Action，需要明确指定分页响应Schema
        responses={
            200: PermissionListSerializer(many=True),  # 让DRF自动包装为分页响应
            404: NotFoundErrorResponseSerializer,
        }
    )
    @action(detail=True, methods=['get'])
    def permissions(self, request, pk=None):
        """获取组权限列表 - 模式1：配置式强制分页"""
        group = self.get_object()

        # 获取基础查询集
        queryset = group.permissions.all().select_related('content_type')

        # 🔑 关键：使用配置式的搜索、过滤、排序
        queryset = self.apply_action_filters(queryset, request, self.get_action_config('permissions'))

        # 🔑 关键：完全模拟ViewSet的分页逻辑
        page = self.paginate_queryset_if_configured(queryset, 'permissions')
        if page is not None and page != 'NO_PAGINATION':  # 与ViewSet的list方法逻辑完全一致
            # 分页响应
            serializer = PermissionListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        # 非分页响应 - 使用原始queryset而不是page
        serializer = PermissionListSerializer(queryset, many=True)
        return self.success_response(serializer.data, "获取组权限列表成功")

    @extend_schema(
        summary="获取组用户列表",
        description="获取指定组的用户列表，支持分页、搜索、过滤、排序",
        parameters=[
            # 可以省略page, page_size, ordering, search
            # 按需要定义,
            OpenApiParameter(name='is_active', type=OpenApiTypes.BOOL, description='是否激活'),
            OpenApiParameter(name='is_staff', type=OpenApiTypes.BOOL, description='是否为管理员'),
        ],
        # 如果不需要reqeust.data需要明确
        request=None,
        responses={
            # 200: create_success_response_serializer(GroupUserListSerializer(many=True), "获取组用户列表成功", "Users"),
            200: GroupUserListSerializer(many=True)

        }
    )
    @action(detail=True, methods=['get'])
    def users(self, request, pk=None):
        """获取组用户列表 - 模式3：配置式强制不分页"""
        group = self.get_object()

        # 获取基础查询集 - 优化查询性能
        queryset = group.user_set.all().prefetch_related('groups')

        # 🔑 关键：使用配置式的搜索、过滤、排序
        queryset = self.apply_action_filters(queryset, request, self.get_action_config('users'))

        # 🔑 关键：完全模拟ViewSet的分页逻辑
        page = self.paginate_queryset_if_configured(queryset, 'users')
        if page is not None and page != 'NO_PAGINATION':  # 与ViewSet的list方法逻辑完全一致
            # 分页响应
            serializer = GroupUserListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        # 非分页响应 - 使用原始queryset而不是page
        serializer = GroupUserListSerializer(queryset, many=True)
        return self.success_response(serializer.data, "获取组用户列表成功")

    @extend_schema(
        summary="批量移除组用户",
        description="批量从指定组中移除用户",
        request=RemoveUsersFromGroupSerializer,
        responses={
            200: create_success_response_serializer(GroupDetailSerializer, "用户移除成功", "RemoveUsers"),
            400: ValidationErrorResponseSerializer,
            404: NotFoundErrorResponseSerializer,
        }
    )
    @action(detail=True, methods=['post'])
    def remove_users(self, request, pk=None):
        """批量从组中移除用户"""
        group = self.get_object()

        serializer = RemoveUsersFromGroupSerializer(data=request.data)
        if not serializer.is_valid():
            return self.error_response("参数无效", errors=serializer.errors, code=400)

        user_ids = serializer.validated_data['user_ids']

        with transaction.atomic():
            # 获取要移除的用户
            users_to_remove = User.objects.filter(id__in=user_ids)

            # 检查用户是否在组中
            users_in_group = group.user_set.filter(id__in=user_ids)
            if users_in_group.count() != len(user_ids):
                not_in_group_ids = set(user_ids) - set(users_in_group.values_list('id', flat=True))
                return self.error_response(
                    f"部分用户不在该组中: {list(not_in_group_ids)}",
                    code=400
                )

            # 从组中移除用户
            group.user_set.remove(*users_to_remove)

            # 删除对应的分配记录
            UserGroupAssignment.objects.filter(
                user__in=users_to_remove,
                group=group
            ).delete()

        response_serializer = GroupDetailSerializer(group)
        return self.success_response(
            data=response_serializer.data,
            message=f"成功移除{len(user_ids)}个用户"
        )


@extend_schema_view(
    list=extend_schema(
        summary="获取用户组分配记录列表",
        description="获取用户组分配记录列表，支持分页、过滤和排序",
        parameters=[
            OpenApiParameter(name='user', type=OpenApiTypes.INT, description='用户ID过滤'),
            OpenApiParameter(name='group', type=OpenApiTypes.INT, description='组ID过滤'),
            OpenApiParameter(name='is_active', type=OpenApiTypes.BOOL, description='是否激活'),
        ],
    ),
    create=extend_schema(
        summary="创建用户组分配记录",
        responses={
            201: create_success_response_serializer(UserGroupAssignmentSerializer, "创建成功", "Create"),
            400: ValidationErrorResponseSerializer,
            403: ForbiddenErrorResponseSerializer,
        }
    ),
    destroy=extend_schema(
        summary="删除用户组分配记录",
        responses={
            204: None,
            404: NotFoundErrorResponseSerializer,
            403: ForbiddenErrorResponseSerializer,
        }
    ),
)
class UserGroupAssignmentViewSet(ApiResponseMixin, viewsets.ModelViewSet):
    """用户组分配记录管理ViewSet"""
    queryset = UserGroupAssignment.objects.all().select_related('user', 'group', 'assigned_by').order_by('-assigned_at')
    serializer_class = UserGroupAssignmentSerializer
    permission_classes = [IsAdminUser]
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['user', 'group', 'is_active']
    search_fields = ['user__username', 'group__name']
    ordering_fields = ['assigned_at', 'expires_at']
    ordering = ['-assigned_at']

    # 只允许创建和删除，不允许更新
    http_method_names = ['get', 'post', 'delete', 'head', 'options']

    @extend_schema(
        summary="获取当前用户权限",
        request=None,
        responses={
            200: create_success_response_serializer(UserPermissionSerializer, "获取成功", "GetUserPermissions"),
            401: NotFoundErrorResponseSerializer,
        }
    )
    @action(detail=False, methods=['get'])
    def user_permissions(self, request):
        """获取当前登录用户的权限和组信息"""
        user = request.user

        if not user.is_authenticated:
            return self.error_response("用户未登录", code=401)

        # 获取用户的所有组
        groups = user.groups.all()

        # 获取权限代码名列表（Django格式：app_label.codename）
        permissions = set()  # 使用set避免重复

        # 获取通过组获得的权限
        for group in groups:
            for perm in group.permissions.all():
                app_label = perm.content_type.app_label
                permissions.add(f"{app_label}.{perm.codename}")

        # 获取直接分配给用户的权限
        for perm in user.user_permissions.all():
            app_label = perm.content_type.app_label
            permissions.add(f"{app_label}.{perm.codename}")

        # 获取组名列表
        group_names = list(groups.values_list('name', flat=True))

        data = {
            'user_id': user.id,
            'permissions': list(permissions),  # 转换set为list
            'groups': group_names
        }

        return self.success_response(
            data=data,
            message="获取成功"
        )


